package RJ;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Evaluator {
	private AssignmentTable at;
	private GroupTable gt;
	private ProjectTable projt;
	private PersonTable pt;
	private int sc1;
	private ArrayList<Person> sc1_p;
	private int sc2;
	private ArrayList<Person> sc2_p;
	private int sc3;
	private ArrayList<Group> sc3_g;
	private int sc4;
	private ArrayList<Room> sc4_r;
	private int sc5;
	private int sc6;
	private int sc7;
	private int sc8;
	private int sc9;
	private int sc10;
	private int sc11;
	private int sc12;
	private int sc13;
	private int sc14;
	private int sc15;
	private int sc16;

	
	public Evaluator(AssignmentTable at, GroupTable gt, ProjectTable projt, PersonTable pt){
		this.at = at;
		this.gt = gt;
		this.projt = projt;
		this.pt = pt;
	}
	
	public int value(){
		int value = 0;
		value += eval_sc1();

		
		value += eval_sc2();
		value += eval_sc3();
		value += eval_sc4();
		value += eval_sc5();
		value += eval_sc6();
		value += eval_sc7();
		value += eval_sc8();

		
		value += eval_sc9();

		value += eval_sc10();

		value += eval_sc11();
		value += eval_sc12();
		

		value += eval_sc13();
		value += eval_sc15();
		value += eval_sc16();
		
		return value;
	}
	
	public int eval_sc1(){
		this.sc1 = 0;
		this.sc1_p = new ArrayList<Person>();
		for(Map.Entry<String, Group> entry:gt.getGT().entrySet()){
			if(entry.getValue().getGroupHead()!=null&&at.getAT().get(entry.getValue().getGroupHead())!=null){
				Person p = entry.getValue().getGroupHead();
				Room r = at.getAT().get(p);
				if(r.getRoomSize()!=RoomSize.LARGEROOM){
					sc1_p.add(p);
					sc1 -= 40;
				}
			}
		}
		return sc1;
	}
	public int eval_sc2(){
		this.sc2 = 0;
		this.sc2_p = new ArrayList<Person>();
		for(Map.Entry<String, Group> entry : gt.getGT().entrySet()){
			Group g = entry.getValue();
			if(g.getGroupHead()!=null&&at.getAT().get(g.getGroupHead())!=null){
				Person gh = g.getGroupHead();
				Room r_gh = at.getAT().get(gh);
				for(Person p : g.groupMember){
					if(p!=gh){
						Room r_gmem = at.getAT().get(p);
						if(!r_gh.CloseTo.contains(r_gmem)){
							sc2 -= 2;
							sc2_p.add(p);
						}
					}
				}
			}
		}
		return sc2;
	}
	public int eval_sc3(){
		this.sc3 = 0;
		this.sc3_g = new ArrayList<Group>();
		for(Map.Entry<String, Group> entry : gt.getGT().entrySet()){
			Group g = entry.getValue();
			int ghCloseS = 0;
			if(g.getGroupHead()!=null){
				Person gh = g.getGroupHead();
				Room r_gh = at.getAT().get(gh);
				for(Person p : g.groupMember){
					if(p.getRole() == ROLE.SECRETARY){
						Room r_s = at.getAT().get(p);
						if(!r_gh.CloseTo.contains(r_s)){
							ghCloseS = -30;
						}else{
							ghCloseS = 0;
						}
					}			
				}
			}
			if(ghCloseS == -30)	sc3_g.add(g);
			this.sc3 += ghCloseS;
		}
		return sc3;
	}
	public int eval_sc4(){
		this.sc4 = 0;
		ArrayList<Room> tmp = new ArrayList<Room>();
		for(Map.Entry<Person, Room> entry : at.getAT().entrySet()){
			Person p = entry.getKey();
			if(p.getRole() == ROLE.SECRETARY){
				Room r = entry.getValue();
				if(!tmp.contains(r)){
					tmp.add(r);
				}else{
					tmp.remove(r);
				}
			}
		}
		this.sc4_r = tmp;
		this.sc4 = tmp.size() * (-5);
		return sc4;
	}
	public int eval_sc5(){
		this.sc5 = 0;
		for(Map.Entry<String, Group> entry : gt.getGT().entrySet()){
			Group g = entry.getValue();
			if(g.getGroupManager()!=null){
				Person gm = g.getGroupManager();
				Room r_gm = at.getAT().get(gm);
				int g_mark = -20;
				for(Person p:g.groupMember){
					if(p.getRole()==ROLE.SECRETARY){
						if(r_gm.CloseTo.contains(at.getAT().get(p))){
							g_mark = 0;
							break;
						}
					}
				}
				this.sc5 += g_mark;
			}
		}
		return this.sc5;
	}
	public int eval_sc6(){
		this.sc6 = 0;
		for(Map.Entry<String, Group> entry : gt.getGT().entrySet()){
			int ghCgm = -20;
			Group g = entry.getValue();
			if(g.getGroupHead() != null && g.getGroupManager() != null){
				Person gh = g.getGroupHead();
				Room r_gh = at.getAT().get(gh);
				Person gm = g.getGroupManager();
				Room r_gm = at.getAT().get(gm);
				if(r_gm.CloseTo.contains(r_gh))	ghCgm = 0;
				else this.sc6 += ghCgm;
			}
		}
		return this.sc6;
	}
	public int eval_sc7(){
		this.sc7 = 0;
		for(Map.Entry<String, Group> entry : gt.getGT().entrySet()){
			Group g = entry.getValue();
			if(g.getGroupManager()!=null&&at.getAT().get(g.getGroupManager())!=null){
				Person gm = g.getGroupManager();
				Room r_gm = at.getAT().get(gm);
				for(Person p : g.groupMember){
					Room r_gmem = at.getAT().get(p);
					if(gm!=p&&!r_gm.CloseTo.contains(r_gmem))	this.sc7 -= 2;
				}
			}
		}
		return sc7;
	}
	public int eval_sc8(){
		this.sc8 = 0;
		for(Map.Entry<String, Project> entry : projt.getPrjTable().entrySet()){
			Project prj = entry.getValue();
			if(prj.getProjectHead()!=null){
				Person ph = prj.getProjectHead();
				Room r_ph = at.getAT().get(ph);
				for(Person p : prj.getProjectMembers()){
					if(p!=ph){
						Room r_pmem = at.getAT().get(p);
						if(!r_ph.CloseTo.contains(r_pmem)){
							sc8 -= 5;
						}
					}
				}
			}
		}
		return sc8;
	}
	public int eval_sc9(){
		this.sc9 = 0;
		for(Map.Entry<String, Project> entry : projt.getPrjTable().entrySet()){
			if(entry.getValue().isLargeProject()){
				int mark = -10;
				Project prj = entry.getValue();
				if(prj.getProjectHead()!=null){
					Person prjh = prj.getProjectHead();
					Room r_prjh = at.getAT().get(prjh);
					if(prjh.getGroup()!=null){
						Group g = prjh.getGroup();
						for(Person p:g.groupMember){
							if(p.getRole()==ROLE.SECRETARY&&at.getAT().get(p)!=null){
								Room r_s = at.getAT().get(p);
								if(r_prjh.CloseTo.contains(r_s)){
									mark = 0;
									break;
								}
							}
						}
						this.sc9 += mark;
					}
				}
			}
		}
		return this.sc9;
	}
	public int eval_sc10(){
		this.sc10 = 0;
		for(Map.Entry<String, Project> entry : projt.getPrjTable().entrySet()){
			int mark = -10;
			if(entry.getValue().isLargeProject()){
				Project prj = entry.getValue();
				if(prj.getProjectHead()!=null){
					Person prjh = prj.getProjectHead();
					if(prjh.getGroup().getGroupHead()!=null){
						Person gh = prjh.getGroup().getGroupHead();
						Room r_gh = at.getAT().get(gh);
						Room r_prjh = at.getAT().get(prjh);
						//System.out.println(r_gh);
						//System.out.println(r_prjh);
						if(r_gh.CloseTo.contains(r_prjh))	mark = 0;
					}
					this.sc10 += mark;
				}
			}
		}
		return this.sc10;
	}
	public int eval_sc11(){
		this.sc11 = 0;
		ArrayList<Room> rl = new ArrayList<Room>();
		for(Map.Entry<String, Person> entry : pt.getPT().entrySet()){
			Person p = entry.getValue();
			if(p.isSmoker()){
				Room r = at.getAT().get(p);
				if(rl.contains(r)){
					rl.remove(r);
				}else{
					rl.add(r);
				}
			}
		}
		for(Map.Entry<String, Person> entry : pt.getPT().entrySet()){
			Person p = entry.getValue();
			if(!p.isSmoker()){
				Room r = at.getAT().get(p);
				if(rl.contains(r))	this.sc11 -= 50;
			}
		}
		return this.sc11;
	}
	public int eval_sc12(){
		this.sc12 = 0;
		for(Map.Entry<String, Project> entry:projt.getPrjTable().entrySet()){
			Project prj = entry.getValue();
			int mark = 0;
			if(prj.getProjectMembers().size() >= 2){
				ArrayList<Room> rl = new ArrayList<Room>();
				for(Person p :prj.getProjectMembers()){
					Room r = at.getAT().get(p);
					if(!rl.contains(r)){
						rl.add(r);
					}else{
						mark -= 14;
					}
				}
			}
			this.sc12 += mark;
		}
		return this.sc12;
	}
	public int eval_sc13(){
		this.sc13 = 0;
		ArrayList<Room> rl = new ArrayList<Room>();
		for(Map.Entry<String, Person> entry:pt.getPT().entrySet()){
			Person p = entry.getValue();
			if(p.getRole()!=ROLE.SECRETARY&&p.isHacker()){
				Room r = at.getAT().get(p);
				if(rl.contains(r))	rl.remove(r);
				else	rl.add(r);
			}
		}
		for(Map.Entry<Person, Room> entry:at.getAT().entrySet()){
			Person p = entry.getKey();
			if(p.getRole()!=ROLE.SECRETARY&&!p.isHacker()){
				Room r = at.getAT().get(p);
				if(rl.contains(r)){
					this.sc13 -= 2;
				}
			}
		}
		return this.sc13;
	}
	public int eval_sc15(){
		this.sc15 = 0;
		for(Map.Entry<Person, Room> entry:at.getAT().entrySet()){
			Person p1 = entry.getKey();
			Room r1 = entry.getValue();
			for(Map.Entry<Person, Room> entry1:at.getAT().entrySet()){
				Person p2 = entry1.getKey();
				Room r2 = entry1.getValue();
				if(p2!=p1&&r1==r2&&!p1.WorkWith.contains(p2)){
					this.sc15 -= 3;
					break;
				}
			}
		}
		return this.sc15;
	}
	public int eval_sc16(){
		this.sc16 = 0;
		for(Map.Entry<Person, Room> entry:at.getAT().entrySet()){
			Person p1 = entry.getKey();
			Room r1 = entry.getValue();
			for(Map.Entry<Person, Room> entry1:at.getAT().entrySet()){
				Person p2 = entry1.getKey();
				Room r2 = entry1.getValue();
				if(p2!=p1&&r1==r2&&r1.getRoomSize()==RoomSize.SMALLROOM){
					this.sc16 -= 25;
					break;
				}
			}
		}
		return this.sc16;
	}
}
